package org.nw.utils;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.nw.constants.Constants;
import org.nw.dao.NWDao;
import org.nw.exception.BusiException;
import org.nw.jf.UiConstants;
import org.nw.vo.sys.ParameterVO;
import org.nw.web.utils.WebUtils;

/**
 * 参数工具类，用来操作nw_parameter表
 * <p>
 * 因为系统的参数一般不常改动，这里做了一次缓存,以参数名称和公司作为key
 * </p>
 * 
 * @author xuqc
 * @date 2012-7-3 下午03:04:11
 */
public class ParameterHelper {

	static Logger logger = Logger.getLogger(ParameterHelper.class);

	public static final String PAGE_SIZE_PARAM = "pageSize";
	public static final String CURRENCY_PARAM = "currency"; // 币种
	public static final String SYSTEM_LOG_PARAM = "systemLog";// 是否记录操作日志
	public static final String PRECISION = "precision";// 精度
	public static final String PAY_DEVI_TYPE = "PAY_DEVI_TYPE";// 分摊类型
	public static final String PLAN_REFRESH_PERIOD = "PLAN_REFRESH_PERIOD";// 运输计划刷新的周期，单位：分钟
	public static final String TRANS_FEE_CODE = "trans_fee_code";// 费用类型中，运费的编码，经常需要根据运费和非运费进行统计
	public static final String CUST_CLAIMANT_CODE = "cust_claimant_code";// 费用类型中，客户索赔的编码
	public static final String CARR_CLAIMANT_CODE = "carr_claimant_code";// 费用类型中，承运商索赔的编码

	// 以参数名称和公司作为key
	private static ConcurrentHashMap<String, String> PARAM_CACHE_MAP = new ConcurrentHashMap<String, String>();

	/**
	 * 读取当前登录公司的所有配置参数
	 * 
	 * @return
	 */
	public static List<ParameterVO> getParamVOs(String pk_corp) {
		NWDao dao = NWDao.getInstance();
		String sql = "select * from nw_parameter where isnull(dr,0)=0";
		if(pk_corp.equals(Constants.SYSTEM_CODE)) {
			sql += " and (pk_corp is null or pk_corp=?)";
		} else {
			sql += " and pk_corp=?";
		}
		return dao.queryForList(sql, ParameterVO.class, pk_corp);
	}

	private static String getCacheKey(String param_code) {
		return param_code + getPkCorp();
	}

	private static String getPkCorp() {
		String pk_corp = "";
		if(WebUtils.getLoginInfo() != null && WebUtils.getLoginInfo().getPk_corp() != null) {
			// 还没有登陆的情况
			pk_corp = WebUtils.getLoginInfo().getPk_corp();
		} else {
			pk_corp = Constants.SYSTEM_CODE;
		}
		return pk_corp;
	}

	/**
	 * 根据参数key返回参数值，如果公司存在参数则优先读取公司参数，否则读取集团参数
	 * 
	 * @param param_key
	 * @param defaultValue
	 * @return
	 */
	public static String getParamValue(String param_key, String defaultValue) {
		String value = PARAM_CACHE_MAP.get(getCacheKey(param_key));
		if(StringUtils.isBlank(value)) {
			String pk_corp = getPkCorp();
			List<ParameterVO> paramVOs = getParamVOs(pk_corp);
			ParameterVO target = null;
			for(ParameterVO paramVO : paramVOs) {
				if(paramVO.getParam_name().equals(param_key)) {
					target = paramVO;
					break;
				}
			}
			if(target == null) {
				// 当前公司没有定义该参数，从集团参数中读取
				paramVOs = getParamVOs(Constants.SYSTEM_CODE);
				for(ParameterVO paramVO : paramVOs) {
					if(paramVO.getParam_name().equals(param_key)) {
						target = paramVO;
						break;
					}
				}
			}
			if(target == null) {
				// 压根没有定义该参数,返回默认
				if(defaultValue == null) {
					throw new BusiException("系统没有定义名称为[" + param_key + "]的参数，请联系管理员！");
				} else {
					value = defaultValue;
				}
			} else {
				value = target.getParam_value();
			}
			PARAM_CACHE_MAP.put(getCacheKey(param_key), value);
		}
		return value;
	}

	/**
	 * 根据参数key返回参数值，如果公司存在参数则优先读取公司参数，否则读取集团参数
	 * 
	 * @param param_key
	 * @return
	 */
	public static String getParamValue(String param_key) {
		return getParamValue(param_key, null);
	}

	/**
	 * 根据参数key返回参数值,转换成int型
	 * 
	 * @param param_key
	 * @return
	 */
	public static int getIntParam(String param_key) {
		String value = getParamValue(param_key);
		if(StringUtils.isBlank(value)) {
			return 0;
		}
		return Integer.parseInt(value.trim());
	}

	/**
	 * 根据参数key返回参数值,转换成double型
	 * 
	 * @param param_key
	 * @return
	 */
	public static double getDoubleParam(String param_key) {
		String value = getParamValue(param_key);
		if(StringUtils.isBlank(value)) {
			return 0;
		}
		return Double.parseDouble(value.trim());
	}

	/**
	 * 根据参数key返回参数值,转换成boolean型
	 * 
	 * @param param_key
	 * @return
	 */
	public static boolean getBooleanParam(String param_key) {
		String value = getParamValue(param_key);
		if(StringUtils.isBlank(value)) {
			return false;
		}
		return Boolean.parseBoolean(value.trim());
	}

	/**
	 * 读取参数配置中的每页记录数
	 * 
	 * @return
	 */
	public static int getPageSize() {
		String value = getParamValue(PAGE_SIZE_PARAM, String.valueOf(Constants.DEFAULT_PAGESIZE));
		return Integer.parseInt(value);
	}

	/**
	 * 读取参数配置中的
	 * 
	 * @return
	 */
	public static String getCurrency() {
		String currency = getParamValue(CURRENCY_PARAM, "");
		if(StringUtils.isBlank(currency)) {
			logger.info("系统参数中必须定义默认的币种，参数名称：" + CURRENCY_PARAM);
		}
		return currency;
	}

	/**
	 * 读取参数配置中的
	 * 
	 * @return
	 */
	public static boolean getSystemLog() {
		String value = getParamValue(SYSTEM_LOG_PARAM, Constants.N);
		return Constants.Y.equalsIgnoreCase(value);
	}

	/**
	 * 读取默认精度
	 * 
	 * @return
	 */
	public static int getPrecision() {
		String value = getParamValue(PRECISION, String.valueOf(UiConstants.DEFAULT_PRECISION));
		return Integer.parseInt(value);
	}

	/**
	 * 应付明细的分摊类型
	 * 
	 * @return
	 */
	public static String getPayDeviType() {
		String payDeviType = getParamValue(PAY_DEVI_TYPE, "");
		if(StringUtils.isBlank(payDeviType)) {
			throw new RuntimeException("系统参数中必须定义默认的分摊类型，参数名称：" + PAY_DEVI_TYPE);
		}
		return payDeviType;
	}

	/**
	 * 费用类型中的运费
	 * 
	 * @return
	 */
	public static String getTransFeeCode() {
		String transFeeCode = getParamValue(TRANS_FEE_CODE, "");
		if(StringUtils.isBlank(transFeeCode)) {
			throw new RuntimeException("系统参数中必须定义默认的运费编码，参数名称：" + TRANS_FEE_CODE);
		}
		return transFeeCode;
	}

	/**
	 * 费用类型中的客户索赔
	 * 
	 * @return
	 */
	public static String getCustClaimantCode() {
		String transFeeCode = getParamValue(CUST_CLAIMANT_CODE, "");
		if(StringUtils.isBlank(transFeeCode)) {
			throw new RuntimeException("系统参数中必须定义默认的客户索赔编码，参数名称：" + CUST_CLAIMANT_CODE);
		}
		return transFeeCode;
	}

	/**
	 * 费用类型中的承运商索赔
	 * 
	 * @return
	 */
	public static String getCarrClaimantCode() {
		String transFeeCode = getParamValue(CARR_CLAIMANT_CODE, "");
		if(StringUtils.isBlank(transFeeCode)) {
			throw new RuntimeException("系统参数中必须定义默认的承运商索赔编码，参数名称：" + CARR_CLAIMANT_CODE);
		}
		return transFeeCode;
	}

	/**
	 * 运输计划自动刷新的时间
	 * 
	 * @return
	 */
	public static int getPlanRefreshPeriod() {
		String value = getParamValue(PLAN_REFRESH_PERIOD, String.valueOf(10));
		return Integer.parseInt(value) * 60 * 1000;
	}
}
